
import re
import pymongo
from django.db.models.loading import get_models
from django.db.models.fields import AutoField, FieldDoesNotExist
from django.db.models.options import Options
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from django.core import urlresolvers 

def _replace(org_func, new_func, *args, **kwargs):

    def _f(*args,**kwargs):
        #org_func(*args,**kwargs)
        return new_func(org_func,*args,**kwargs)
    return _f

def fix_django():

    for model in get_models():
        if model.__module__.startswith('django.contrib'):
            fix_model(model)

    def auto_field_get_prep_value(self, value):
        if value is None:
            return None

        if isinstance(value, (str,unicode) ):
            return pymongo.objectid.ObjectId(value)
        return value

    def auto_field_to_python(self, value):
        return value

    AutoField.get_prep_value = auto_field_get_prep_value
    AutoField.to_python = auto_field_to_python

def model_getattr(self, attrname ):
    if attrname == 'id':
        return getattr( self, '_id' )
    raise AttributeError(attrname)

def options_get_field_by_name(org_func, name):

    try:
        f = org_func( name )
        return f
    except FieldDoesNotExist:
        if name == 'id':
            f = org_func( '_id' )
            return f
        raise FieldDoesNotExist(name)

def options_get_field(org_func, name, many_to_many=True):

    try:
        f = org_func( name )
        return f
    except FieldDoesNotExist:
        if name == 'id':
            f = org_func( '_id' )
            return f
        raise FieldDoesNotExist(name)

def fix_model(model):
    meta = model._meta
    if meta.pk.name == 'id':
        pk_index = meta.pk_index()
        auto = AutoField(verbose_name='_id', primary_key=True,
                auto_created=True)
        auto.model = model
        auto.set_attributes_from_name('_id')
        meta.pk = auto
        meta.local_fields[ pk_index ] = auto
        meta._fill_fields_cache()
        meta.init_name_map()
    model.__getattr__ = model_getattr
    meta.get_field_by_name = _replace( meta.get_field_by_name, options_get_field_by_name )
    meta.get_field = _replace( meta.get_field, options_get_field)

def fix_urls(urls):
    def user_admin_get_urls(org_func, self):
        from django.conf.urls.defaults import patterns
        #from django.core.urlresolvers import patterns
        ptns =  patterns('',
            (r'^(\w+)/password/$', self.admin_site.admin_view(self.user_change_password))
                                    )
        ptns += org_func(self)
        return ptns

    UserAdmin.get_urls = _replace( UserAdmin.get_urls, user_admin_get_urls)

